<template>
  <div>
    <el-dialog
      :title="title"
      width="1200px"
      custom-class="config-option-dialog"
      :close-on-click-modal="false"
      :visible="visible"
      @close="$emit('close')"
    >
      <div v-loading="loading.record">
        <el-form
          :model="formData"
          :rules="rules"
          ref="form"
          label-width="100px"
        >
          <el-form-item label="规则描述" prop="description">
            <el-input
              v-model="formData.description"
              placeholder="请输入"
            ></el-input>
          </el-form-item>
          <el-form-item label="预警对象" prop="warningObject" class="tag-list">
            <el-tag
              closable
              v-for="user in warningObjectList"
              :key="user.id"
              size="medium"
              @close="removeUserById(user.id)"
            >
              {{ user.realName }}
            </el-tag>
            <el-popover
              v-model="popVisible"
              placement="bottom"
              title="添加预警对象"
              trigger="click"
              popper-class="user-select-pop"
            >
              <el-button
                plain
                slot="reference"
                type="primary"
                size="mini"
                icon="el-icon-plus"
                class="add-btn"
                @click="showUserSelectPop"
              >
                添加
              </el-button>
              <div class="user-select-wrapper">
                <el-input
                  v-model="keyword"
                  size="small"
                  placeholder="搜索用户名"
                  @keyup.native.enter="onSearch"
                >
                  <el-button
                    slot="append"
                    icon="el-icon-search"
                    @click="onSearch"
                  />
                </el-input>
                <div class="dept-tree" v-loading="loading.tree">
                  <el-tree
                    ref="tree"
                    lazy
                    show-checkbox
                    node-key="id"
                    :props="treeProps"
                    :data="deptTree"
                    :load="loadNode"
                  >
                    <template slot-scope="{ data }">
                      <span :title="data.name">{{
                        data.name || data.realName || data.username
                      }}</span>
                    </template>
                  </el-tree>
                </div>
              </div>
              <div class="button-group">
                <el-button size="mini" type="primary" @click="handleSelectOk"
                  >确定</el-button
                >
                <el-button size="mini" @click="popVisible = false"
                  >取消</el-button
                >
              </div>
            </el-popover>
          </el-form-item>
          <el-form-item label="是否启用" prop="isUsed">
            <el-switch
              v-model="formData.isUsed"
              inactive-value="1"
              active-value="0"
            >
            </el-switch>
          </el-form-item>
          <el-form-item label="计算方式" prop="rulesMethodDtoList">
            <el-table
              ref="table"
              size="small"
              :data="formData.rulesMethodDtoList"
            >
              <el-table-column prop="leftBracket" width="84" label="符号">
                <template slot-scope="{ row }">
                  <el-select
                    size="small"
                    v-model="row.leftBracket"
                    placeholder="无"
                  >
                    <el-option label="无" value=""></el-option>
                    <el-option label="(" value="("></el-option>
                  </el-select>
                </template>
              </el-table-column>
              <el-table-column prop="field" label="字段">
                <template slot-scope="{ row }">
                  <el-select
                    size="small"
                    v-model="row.field"
                    placeholder="请选择"
                  >
                    <el-option :label="field" :value="field"></el-option>
                  </el-select>
                </template>
              </el-table-column>
              <el-table-column prop="demension" width="128" label="维度">
                <template slot-scope="{ row }">
                  <el-select
                    size="small"
                    v-model="row.demension"
                    placeholder="请选择"
                  >
                    <el-option label="当前值" value="当前值"></el-option>
                    <el-option label="同比增速" value="同比增速"></el-option>
                    <el-option label="环比增速" value="环比增速"></el-option>
                    <el-option label="同比增量" value="同比增量"></el-option>
                    <el-option label="环比增量" value="环比增量"></el-option>
                  </el-select>
                </template>
              </el-table-column>
              <el-table-column prop="condition" label="条件">
                <template slot-scope="{ row }">
                  <el-select
                    size="small"
                    v-model="row.condition"
                    placeholder="请选择"
                  >
                    <el-option
                      v-for="option of options.typeNumber"
                      :key="option.value"
                      v-bind="option"
                    >
                    </el-option>
                  </el-select>
                </template>
              </el-table-column>
              <el-table-column prop="value" label="值">
                <template slot-scope="{ row }">
                  <el-input
                    size="small"
                    v-model="row.value"
                    placeholder="请输入"
                  ></el-input>
                </template>
              </el-table-column>
              <el-table-column prop="rightBracket" width="84" label="符号">
                <template slot-scope="{ row }">
                  <el-select
                    size="small"
                    v-model="row.rightBracket"
                    placeholder="无"
                  >
                    <el-option label="无" value=""></el-option>
                    <el-option label=")" value=")"></el-option>
                  </el-select>
                </template>
              </el-table-column>
              <el-table-column prop="connect" width="84" label="与/或">
                <template slot-scope="{ row }">
                  <el-select
                    size="small"
                    v-model="row.connect"
                    placeholder="请选择"
                  >
                    <el-option label="无" value=""></el-option>
                    <el-option label="与" value="与"></el-option>
                    <el-option label="或" value="或"></el-option>
                  </el-select>
                </template>
              </el-table-column>
              <el-table-column label="操作" width="136">
                <template slot-scope="{ $index }">
                  <div class="table-operation">
                    <el-link type="primary" @click="addRow($index)"
                      >新增</el-link
                    >
                    <el-link type="primary" @click="clearRow($index)"
                      >清空</el-link
                    >
                    <el-link
                      type="danger"
                      @click="deleteRow($index)"
                      :disabled="formData.rulesMethodDtoList.length <= 1"
                      >删除</el-link
                    >
                  </div>
                </template>
              </el-table-column>
            </el-table>
            <div class="text-value" v-html="textValue"></div>
          </el-form-item>
        </el-form>
      </div>
      <template #footer>
        <div class="footer-btn">
          <el-button
            type="primary"
            :loading="loading.submit"
            @click="handleSubmit"
          >
            保存
          </el-button>
          <el-button @click="$emit('close')"> 取消 </el-button>
        </div>
      </template>
    </el-dialog>
  </div>
</template>

<script>
import {encrypt} from "@/utils/sm4Utils";
import { encryptECB, decryptECB } from "@/utils/encryptAndDecryptUtils";

export default {
  props: {
    visible: {
      type: Boolean,
      default: false,
    },
    relationId: {
      type: String,
      default: "",
    },
    id: {
      type: String,
      default: "",
    },
    field: {
      type: String,
      default: "",
    },
  },
  data() {
    return {
      DEFAULT_DATA: Object.freeze({
        leftBracket: "",
        field: "",
        demension: "",
        condition: "",
        value: "",
        rightBracket: "",
        connect: "",
      }),
      formData: {
        description: "",
        warningObject: "",
        isUsed: "0",
        rulesMethodDtoList: [],
      },
      rules: {
        description: [
          { required: true, message: "请输入规则描述", trigger: "change" },
        ],
        warningObject: [
          { required: true, message: "请添加预警对象", trigger: "change" },
        ],
        isUsed: [
          { required: true, message: "请选择是否启用", trigger: "change" },
        ],
        rulesMethodDtoList: [
          { required: true, message: "请配置计算方式", trigger: "change" },
        ],
      },
      options: {
        typeNumber: [
          { label: ">", value: ">" },
          { label: "<", value: "<" },
          { label: ">=", value: ">=" },
          { label: "<=", value: "<=" },
          { label: "==", value: "==" },
          { label: "!=", value: "!=" },
          { label: "interval", value: "interval" },
          { label: "is null", value: "is null" },
          { label: "is not null", value: "is not null" },
          { label: "is empty", value: "is empty" },
          { label: "is not empty", value: "is not empty" },
        ],
        typeString: [
          { label: "==", value: "==" },
          { label: "!=", value: "!=" },
          { label: "like", value: "like" },
          { label: "not like", value: "not like" },
          { label: "is null", value: "is null" },
          { label: "is not null", value: "is not null" },
          { label: "is empty", value: "is empty" },
          { label: "is not empty", value: "is not empty" },
        ],
      },
      loading: {
        record: false,
        tree: false,
        submit: false,
      },
      record: {},
      warningObjectList: [],
      popVisible: false,
      keyword: "",
      deptTree: [],
      treeProps: {
        isLeaf: "isLeaf",
      },
    };
  },
  computed: {
    title() {
      return this.id ? "编辑规则" : "新增规则";
    },
    textValue() {
      let html = "";
      for (const item of this.formData.rulesMethodDtoList) {
        html += `${item.leftBracket}${item.field} ${item.demension} ${item.condition} ${item.value}${item.rightBracket} ${item.connect}<br />`;
      }
      return html;
    },
  },
  watch: {
    visible(newVisible) {
      if (newVisible) {
        // 重置表单
        this.resetForm();
        this.formData.rulesMethodDtoList[0].field = this.field;

        // 如果是编辑，获取记录
        if (this.id) {
          this.fetchRecordData();
        }
      }
    },
  },
  mounted() {
    this.formData.rulesMethodDtoList = [{ ...this.DEFAULT_DATA }];
  },
  methods: {
    handleSubmit() {
      this.$refs.form.validate(async (valid) => {
        if (valid) {
          // 要提交的表单数据
          const method = this.textValue.replace(/<br \/>/g, "\n");
          // 为计算方式表格添加sort排序
          const rulesMethodDtoList = this.formData.rulesMethodDtoList.map(
            (item, index) => {
              return { ...item, sort: index };
            }
          );
          const data = {
            ...this.formData,
            rulesMethodDtoList,
            id: this.id,
            relationId: this.relationId,
            method,
          };
          // 判断是新增还是编辑
          const requestUrl = data.id
            ? "/cgjybzWarningRules/updateRules"
            : "/cgjybzWarningRules/insertRules";
          this.loading.submit = true;
          let params = await encryptECB(JSON.stringify(data));
          let parasJson = JSON.stringify(params);
          let xSecret = await encrypt(parasJson)
          this.$http
            .post(requestUrl, parasJson,{
              headers:{
                "x-secret":xSecret,
                "Content-Type":"application/json",
              },
            })
            .then((res) => {
              this.$message.success(`${this.title}成功`);
              this.$eventBus.$emit('refresh')

              this.$emit("refresh");
              this.$emit("close");
            })
            .catch((e) => {
              this.$message.error(`${this.title}失败，请稍后再试`);
              console.error(`${this.title}失败：`, e);
            })
            .finally(() => {
              this.loading.submit = false;
            });
        }
      });
    },
    async fetchRecordData() {
      const params = { id: this.id };
      this.loading.record = true;
      let params2 = await encryptECB(
        JSON.stringify(params)
      );
      let parasJson = JSON.stringify(params2);
      let xSecret = await encrypt(parasJson);
      this.$http
        .post("/cgjybzWarningRules/getRulesInfo", parasJson,{
            headers: {
              "x-secret":xSecret,
              'Content-Type': 'application/json'
            }
          })
        .then((result) => {
          debugger;
          console.log('result', result)
          decryptECB(result.data.data).then((resData) => {
            let res = JSON.parse(resData);
            debugger;
            console.log('res', res)
            const data = res.data || {};
            this.record = data;
            // 设置表单值
            this.$nextTick(() => {
              for (const key in this.formData) {
                if (key === "warningObject") {
                  // 特殊处理
                  const ids = data.warningObject
                    .split(",")
                    .filter((item) => item);
                  const names = data.warningObjectName
                    .split(",")
                    .filter((item) => item);
                  const warningObjectList = [];
                  for (let i = 0; i < ids.length; i++) {
                    warningObjectList.push({
                      realName: names[i] || ids[i],
                      id: ids[i],
                    });
                  }
                  this.warningObjectList = warningObjectList;
                  this.formData.warningObject = data.warningObject;
                } else {
                  // 通用处理
                  this.formData[key] = data[key];
                }
              }
            });
          })
        })
        .catch((e) => {
          this.$message.error("获取数据失败，请稍后再试");
          console.error(e);
        })
        .finally(() => {
          this.loading.record = false;
        });
    },
    handleSelectOk() {
      // 获取已选的节点
      const checkedNodes = this.$refs.tree.getCheckedNodes();
      // 获取已保存的用户id
      const checkedIds = this.warningObjectList.map((item) => item.id);
      // 过滤掉部门和已保存的数据
      const warningObjectList = checkedNodes.filter(
        (item) => item.username && !checkedIds.includes(item.id)
      );
      // 保存新选的用户
      this.warningObjectList.push(...warningObjectList);
      this.formData.warningObject = this.warningObjectList
        .map((item) => item.id)
        .join(",");
      // 清空树已选的节点
      this.$refs.tree.setCheckedNodes([]);
      // 隐藏弹出层
      this.popVisible = false;
    },
    onSearch() {
      if (this.keyword) {
        this.fetchUserList();
      } else {
        this.fetchDeptTree();
      }
    },
    fetchUserList() {
      this.loading.tree = true;
      const params = { keyWord: this.keyword };
      this.$http
        .get("/sys/user/queryUser", { params })
        .then((res) => {
          const userList = res.data.data || [];
          const deptTree = [{ name: "未分配部门", id: "0", children: [] }];
          // 按部门分组
          for (const user of userList) {
            user.isLeaf = true;
            // 如果用户信息中部门ID和部门名称都有
            if (user.deptId && user.deptName) {
              const dept = deptTree.find((item) => item.id === user.deptId);
              if (dept) {
                // 如果部门已经添加到部门树中，将用户添加到部门下
                dept.children.push(user);
              } else {
                // 否则创建部门信息并添加用户到部门下
                deptTree.unshift({
                  name: user.deptName,
                  id: user.deptId,
                  children: [user],
                });
              }
            } else {
              // 没有完整部门信息的用户，添加到未分配部门中
              deptTree[deptTree.length - 1].children.push(user);
            }
          }
          this.deptTree = deptTree.filter((item) => item.children.length > 0);
          // 默认展开父节点
          this.$nextTick(() => {
            this.deptTree.forEach((item) => {
              const node = this.$refs.tree.getNode(item.id);
              node && node.expand();
            });
          });
        })
        .finally(() => {
          this.loading.tree = false;
        });
    },
    fetchDeptTree() {
      this.loading.tree = true;
      this.$http
        .get("/sys/dept/allDept")
        .then((res) => {
          const data = res.data.data || [];
          this.deptTree = data
            .sort((a, b) => a.sort - b.sort)
            .map((item) => {
              item.disabled = true;
              return item;
            });
        })
        .catch((e) => {
          console.error("获取部门列表失败：", e);
        })
        .finally(() => {
          this.loading.tree = false;
        });
    },
    loadNode(node, resolve) {
      if (this.keyword) {
        return resolve(node.data.children);
      }
      if (node.data?.id) {
        const params = { deptId: node.data.id };
        this.$http
          .get("/sys/user/queryUserByDeptId", { params })
          .then((res) => {
            // console.log(res)
            const data = res.data.data || [];
            data.map((item) => {
              item.isLeaf = true; // 设置用户为叶子节点不可展开
              return item;
            });
            if (data.length > 0) {
              node.data.disabled = false;
            }
            resolve(data);
          });
      } else {
        resolve([]);
      }
    },
    showUserSelectPop() {
      this.keyword = "";
      this.deptTree = [];
      this.fetchDeptTree();
    },
    removeUserById(id) {
      this.warningObjectList = this.warningObjectList.filter(
        (item) => item.id !== id
      );
      this.formData.warningObject = this.warningObjectList
        .map((item) => item.id)
        .join(",");
    },
    deleteRow(index) {
      this.formData.rulesMethodDtoList.splice(index, 1);
    },
    clearRow(index) {
      const data = JSON.parse(JSON.stringify(this.DEFAULT_DATA));
      this.$set(this.formData.rulesMethodDtoList, index, data);
    },
    addRow(index) {
      const data = JSON.parse(JSON.stringify(this.DEFAULT_DATA));
      this.formData.rulesMethodDtoList.splice(index + 1, 0, data);
    },
    resetForm() {
      this.$data.formData = this.$options.data().formData;
      const data = JSON.parse(JSON.stringify(this.DEFAULT_DATA));
      this.$data.formData.rulesMethodDtoList = [data];
      this.warningObjectList = [];
      this.$nextTick(() => {
        this.$refs.form.clearValidate();
      });
    },
  },
};
</script>

<style lang="scss">
.config-option-dialog {
  .el-dialog__body {
    padding: 20px;
  }
  .table-operation {
    > *:not(:last-child) {
      margin-right: 16px;
    }
  }
  .text-value {
    line-height: 2;
    border: 1px solid #eeeeee;
    padding: 10px 20px;
    margin-top: 20px;
  }
  .footer-btn {
    text-align: center;
  }
  .add-btn {
    padding: 4px 8px;
    font-size: 14px;
    border-radius: 40px;
    color: #3d76cc;
    border-color: #3d76cc;
    background-color: rgba(61, 118, 204, 0.25);
    .el-icon-plus {
      font-weight: bold;
    }
  }
  .el-tag {
    height: 24px;
    line-height: 22px;
    color: black;
    border-color: rgba(61, 118, 204, 0.5);
    background-color: rgba(61, 118, 204, 0.1);
    border-radius: 28px;
    margin: 4px 0;
    margin-right: 16px;
    position: relative;
    .el-tag__close {
      position: absolute;
      top: -6px;
      right: -8px;
      color: white;
      background-color: rgba($color: #000000, $alpha: 0.5);
      transform: scale(0.9);
    }
  }
}

.user-select-pop {
  padding: 10px;
  .dept-tree {
    height: 240px;
    overflow-y: auto;
    margin-top: 8px;
  }
  .button-group {
    border-top: 1px solid #cccccc;
    margin-top: 8px;
    padding-top: 8px;
    text-align: center;
  }
}
</style>
